Skip to content

fix(iOS): remove FormSheet scroll view KVO observer synchronously on invalidate#4091

Merged
kkafar merged 5 commits into
software-mansion:mainfrom
phewphewb:fix-form-sheet-scroll-view-clipped
May 25, 2026
Merged

fix(iOS): remove FormSheet scroll view KVO observer synchronously on invalidate#4091
kkafar merged 5 commits into
software-mansion:mainfrom
phewphewb:fix-form-sheet-scroll-view-clipped

Conversation

@phewphewb

Copy link
Copy Markdown
Contributor

Description

Fixes #4090

After dismissing FormSheet, pushed screen ScrollView is clipped to sheet height.
FormSheet KVO observer not removed before scroll view is reused by the next screen.

Changes

  • Remove the FormSheet scroll view KVO observer synchronously at the start of -invalidateImpl, instead of inside the dispatch_async block introduced in feat(iOS, Stack v4): Use new invalidation callback on Fabric #3728
  • Keep deferring _controller - nil to the async block (unchanged)
  • Add Test4090 as a minimal repro for dismissing a form sheet and immediately pushing a screen with a full-height ScrollView

Before & after - visual documentation

Before

Simulator.Screen.Recording.-.iPhone.17.Pro.-.2026-05-22.at.22.59.32.2.mov

After

Simulator.Screen.Recording.-.iPhone.17.Pro.-.2026-05-24.at.18.38.05.mov

Test plan

Checklist

  • Included code example that can be used to test this change.
  • For visual changes, included screenshots / GIFs / recordings documenting the change.
  • For API changes, updated relevant public types.
  • Ensured that CI passes

@phewphewb

Copy link
Copy Markdown
Contributor Author

@kkafar @t0maboro @kligarski

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes an iOS FormSheet-specific regression where a descendant ScrollView could remain clipped to the dismissed sheet’s height because a bounds KVO observer was removed too late (after the scroll view was already reused by the next pushed screen).

Changes:

  • Remove the FormSheet descendant scroll view bounds KVO observer synchronously at the start of -[RNSScreenView invalidateImpl] (instead of deferring it to an async cleanup block).
  • Keep controller cleanup (_controller = nil) deferred to the existing dispatch_async block.
  • Add a minimal issue repro screen (Test4090) and export it in the issue-tests index.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
ios/RNSScreen.mm Ensures the FormSheet scroll view KVO observer is removed immediately during invalidation to prevent reuse-related layout bugs.
apps/src/tests/issue-tests/Test4090.tsx Adds a minimal navigation scenario reproducing “dismiss FormSheet + immediately push ScrollView screen” clipping.
apps/src/tests/issue-tests/index.ts Exposes Test4090 in the issue-tests registry so it appears in the test app.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@kkafar kkafar left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey! Thanks for the contribution.

The patch seems reasonable. I've only added a code comment explaining why it is the case, that we run only scroll-view related part synchronously.

I'll wait for the CI to pass before landing.

@kkafar

kkafar commented May 25, 2026

Copy link
Copy Markdown
Member

The layout direction iOS e2e test failing seems unrelated. @LKuchno FYI

@kkafar kkafar merged commit 228ec9c into software-mansion:main May 25, 2026
5 of 7 checks passed
@phewphewb

Copy link
Copy Markdown
Contributor Author

I am glad I could help!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

After dismissing FormSheet, pushed screen ScrollView is clipped to sheet height

4 participants